package clientes;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import ofertas.Oferta;

import org.junit.Before;
import org.junit.Test;

import cadenaDeSucursales.CadenaSucursales;
import productosYPresentaciones.Producto;
import sucursal.Stock;
import sucursal.Sucursal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.mockito.Mockito.*;
/***
 * Clase test de Cliente.
 * @author Stefania Lilian Chiniewicz.
 *
 */
public class ClienteTest {
	
	Cliente cliente;
	//private List<Producto>ccProductos;
	Stock ccProductos;
	//private float ccPesos;
	private String dni;
	private String domicilio;
	private String email;
	//private List<Oferta> bandejaDeEntrada;
	
	
	
	@Before
	public void setUp() throws Exception {
		this.dni= "36664421";
		this.domicilio= "Dardo Rocha 1518";
		this.email= "slch@gmail.com";
		this.cliente= new Cliente(dni, domicilio, email);

	}

	@Test
	public void testRecibirNotificacionOfertas() {
		//this.bandejaDeEntrada= new ArrayList<Oferta>();
		//cliente.setBandejaDeEntrada(bandejaDeEntrada);
		
		List<Sucursal>sucursales= new ArrayList<Sucursal>();
		List<Cliente>lista= new ArrayList<Cliente>();
		List<Oferta>oferta= new ArrayList<Oferta>();
		Oferta mockO= mock(Oferta.class);
		CadenaSucursales mock= mock(CadenaSucursales.class);
		
		when(mock.getSucursales()).thenReturn(sucursales);
		when(mock.getClientesSubscriptos()).thenReturn(lista);
		when(mock.getOfertasVigentes()).thenReturn(oferta);
		
		mock.agregarSubscriptor(cliente);
		mock.agregarOferta(mockO);
		
		cliente.recibirNotificacionOfertas(mock,mockO);
		
	
		assertTrue(cliente.getBandejaDeEntrada().contains(mockO));
		//verify()

	}
	
	@Test
	public void testagregarACuentaCorrienteProductos(){
		
		Producto c= mock(Producto.class);
		cliente.agregarACuentaCorrienteProductos(c,4);
		
		assertEquals(cliente.getCcProductos().getCantStock(c),4);
	}
	
	@Test
	public void testAgregarACuentaCorrientePesos(){
		//ccPesos= 0f;
		//cliente.setCcPesos(ccPesos);
		cliente.agregarACuentaCorrientePesos(150f);
		
		assertEquals(cliente.getCcPesos(),150f,0.022f);
	}
	
	@Test
	public void testRecibirTicket(){
		Ticket mockT= mock(Ticket.class);
		cliente.recibirTicket(mockT);
		
		assertEquals(1,cliente.getTickets().size());
		
	}
	
	@Test
	public void testRecibirDetalleRetiroEntrega(){
		TicketCcProductos dreMock= mock(TicketCcProductos.class);
		cliente.recibirDetalleRetiroEntrega(dreMock);
		assertEquals(1,cliente.getDetalleRetiroEntrega().size());
	}
	
	@Test
	public void testRecibirDetalleCompra(){
		Ticket dcMock= mock(Ticket.class);
		cliente.recibirDetalleCompra(dcMock);
		assertEquals(1,cliente.getTicketsCCPesos().size());
	}
	
	@Test
	public void descontarDeCCPesosTest(){
		cliente.agregarACuentaCorrientePesos(180f);
		cliente.descontarDeCCPesos(150f);
		assertEquals(30f,cliente.getCcPesos(),0.002f);
	}
	
	@Test
	public void descontarDeCCProductosTest(){
		Producto pMock= mock(Producto.class);
		cliente.agregarACuentaCorrienteProductos(pMock, 8);
		cliente.descontarDeCCProductos(pMock, 4);
		
		assertEquals(4,cliente.getCcProductos().getCantStock(pMock));
	}
	
	@Test
	public void elProductoEstaEnCCProductosTestTrue(){
		Producto pMock= mock(Producto.class);
		cliente.agregarACuentaCorrienteProductos(pMock, 8);
	
		assertTrue(cliente.elProductoEstaEnCCProductos(pMock, 5));
	}
	
	@Test
	public void elProductoEstaEnCCProductosTestFalse(){
		Producto pMock= mock(Producto.class);
		cliente.agregarACuentaCorrienteProductos(pMock, 6);
	
		assertFalse(cliente.elProductoEstaEnCCProductos(pMock, 8));
	}
	
	@Test
	public void puedePagarProductoTestTrue(){
		Producto pMock= mock(Producto.class);
		cliente.agregarACuentaCorrientePesos(180f);
		when(pMock.precioActual()).thenReturn(12f);
		
		assertTrue(cliente.puedePagarProducto(pMock));
	}
	
	@Test
	public void puedePagarProductoTestFalse(){
		Producto pMock= mock(Producto.class);
		cliente.agregarACuentaCorrientePesos(80f);
		when(pMock.precioActual()).thenReturn(120f);
		
		assertFalse(cliente.puedePagarProducto(pMock));
	}
	
	@Test
    public void puedePagarElMontoDesdeCCPesosTestTrue(){
		cliente.agregarACuentaCorrientePesos(150f);
		assertTrue(cliente.puedePagarElMontoDesdeCCPesos(50f));
	}
	
	@Test
    public void puedePagarElMontoDesdeCCPesosTestFalse(){
		cliente.agregarACuentaCorrientePesos(150f);
		assertFalse(cliente.puedePagarElMontoDesdeCCPesos(200f));
	}
	
	@Test
	public void puedePagarLosProductosDesdeCCProductosTrue(){
		Producto productoMock= mock(Producto.class);
		Map<Producto, Integer>unosProductos= new HashMap<Producto,Integer>();
		unosProductos.put(productoMock,5);
		cliente.agregarACuentaCorrienteProductos(productoMock,10);
		
		assertTrue(cliente.puedePagarLosProductosDesdeCCProductos(unosProductos));
	}
	
	@Test
	public void puedePagarLosProductosDesdeCCProductosFalse(){
		Producto productoMock= mock(Producto.class);
		Map<Producto, Integer>unosProductos= new HashMap<Producto,Integer>();
		unosProductos.put(productoMock,10);
		cliente.agregarACuentaCorrienteProductos(productoMock,5);
		
		assertFalse(cliente.puedePagarLosProductosDesdeCCProductos(unosProductos));
	}
	
	@Test
	public void descontarProductosDeCCProductosTest(){
		Producto productoMock= mock(Producto.class);
		Map<Producto, Integer>unosProductos= new HashMap<Producto,Integer>();
		unosProductos.put(productoMock,10);
		cliente.agregarACuentaCorrienteProductos(productoMock,20);
		cliente.descontarDeCCProductos(unosProductos);
		assertEquals(10, cliente.getCcProductos().getCantStock(productoMock) );
	}
	
	}
	
